#! /usr/bin/env python
# -*- coding: utf-8 -*-
#AutoRename.pyw



import sys
import glob
import os
import wx
import EnhancedStatusBar as ESB
import AutoRename as AR
import shortpath



class MainFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        # sets the font
        font = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT)

        # sets the icon
        if sys.platform == 'win32':
            exeName = sys.executable
            icon = wx.Icon(exeName, wx.BITMAP_TYPE_ICO)
            self.SetIcon(icon)
        
        # creates the menubar
        menubar = wx.MenuBar()

        # creates the filemenu
        filemenu = wx.Menu()
        quititem = filemenu.Append(wx.ID_ANY, text='&Quit')
        self.Bind(wx.EVT_MENU, self.onQuit, quititem)
        menubar.Append(filemenu, '&File')

        # initializes the menubar
        self.SetMenuBar(menubar)

        # creates the layout
        self.panel = wx.Panel(self, wx.ID_ANY)
        self.sizer = wx.GridBagSizer(3, 3)
        
        # average charwidth
        self.avwidth = wx.ClientDC(self).GetCharWidth()

        # creates the source self.panel
        static1 = wx.StaticText(self.panel, wx.ID_ANY, 'Source')
        self.text1 = wx.TextCtrl(self.panel, wx.ID_ANY)
        button1 = wx.Button(self.panel, wx.ID_ANY, 'Browse')
        self.Bind(wx.EVT_BUTTON, self.chooseSourceDir, button1)
        self.sizer.Add(static1, (0, 0), (1, 1), wx.ALL | wx.ALIGN_CENTER, border=5)
        self.sizer.Add(self.text1, (0, 1), (1, 1), wx.EXPAND | wx.ALL, 
                       border=5)
        self.sizer.Add(button1, (0, 2), (1, 1), wx.ALL, border=5)

        # creates the target self.panel
        static2 = wx.StaticText(self.panel, wx.ID_ANY, 'Target')
        self.text2 = wx.TextCtrl(self.panel, wx.ID_ANY)
        button2 = wx.Button(self.panel, wx.ID_ANY, 'Browse')
        self.Bind(wx.EVT_BUTTON, self.chooseTargetDir, button2)
        self.sizer.Add(static2, (1, 0), (1, 1), wx.ALL | wx.ALIGN_CENTER, border=5)
        self.sizer.Add(self.text2, (1, 1), (1, 1), wx.EXPAND | wx.ALL, 
                       border=5)
        self.sizer.Add(button2, (1, 2), (1, 1), wx.ALL, border=5)
        
        # creates the type radiobox
        self.radio1 = wx.RadioBox(self.panel, wx.ID_ANY, majorDimension=1, 
                                  style=wx.RA_SPECIFY_COLS, 
                                  choices=['Automatically', 'Custom'])
        self.radio1.SetLabel('Choose your action')
        self.Bind(wx.EVT_RADIOBOX, self.chooseAction, self.radio1)
        self.sizer.Add(self.radio1, (2, 0), (1, 2), wx.ALL, border=5)

        # creates the listctrl
        self.lc1 = wx.ListCtrl(self.panel, wx.ID_ANY, style=wx.LC_REPORT)
        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onLc1Focus, self.lc1)
        self.sizer.Add(self.lc1, (3, 0), (1, 3), wx.EXPAND | wx.ALL, border = 5)
        self.lc1.InsertColumn(0, 'Filename')
        self.lc1.SetColumnWidth(0, 300)   
        
        # creates the output textbox
        text3 = wx.TextCtrl(self.panel, wx.ID_ANY, 
                            style=wx.TE_MULTILINE | wx.TE_READONLY)
        sys.stdout = text3
        sys.stderr = text3
        self.sizer.Add(text3, (4, 0), (1, 3), wx.EXPAND | wx.ALL, border=5)

        # creates the refresh button
        self.butt3 = wx.Button(self.panel, wx.ID_ANY, 'Refresh')
        self.Bind(wx.EVT_BUTTON, self.onRefresh, self.butt3)
        self.sizer.Add(self.butt3, (5, 0), (1, 1), wx.ALL, border=5)
        
        # sourcepath autorefresh
        self.Bind(wx.EVT_SIZE, self.refreshSourcePathLength)

        # creates the start button
        self.butt4 = wx.Button(self.panel, wx.ID_ANY, 'Start')
        self.Bind(wx.EVT_BUTTON, self.runAuto, self.butt4)
        self.sizer.Add(self.butt4, (5, 2), (1, 1), wx.ALL, border=5)
        
        # initialize the print data and set some default values
        #self.pdata = wx.PrintData()
        #self.pdata.SetPaperId(wx.PAPER_LETTER)
        #self.pdata.SetOrientation(wx.PORTRAIT)
        #self.margins = (wx.Point(15,15), wx.Point(15,15))
        
        # creates the statusbar
        self.statusbar = ESB.EnhancedStatusBar(self, wx.ID_ANY)
        self.SetStatusBar(self.statusbar)
        self.setStatusMessage('Welcome to AR 1.3.3')

        # initializes the layout
        self.sizer.AddGrowableCol(1)
        self.sizer.AddGrowableRow(3)
        self.sizer.AddGrowableRow(4)
        self.panel.SetSizerAndFit(self.sizer)

        # some final commands
        self.Centre()
        self.cuts = 0
    
    def onRefresh(self, event):
        self.lc1.DeleteAllItems()       
        files = glob.glob('*.txt')
        for filename in files:
            num_items = self.lc1.GetItemCount()
            self.lc1.InsertStringItem(num_items, filename)

    
    def onLc1Focus(self, event):
        focusid = self.lc1.GetFocusedItem()
        filename = self.lc1.GetItemText(focusid)
        print '{0} has focus'.format(filename)
        
        # creates the print preview
        #printer = Printer(self.panel, file(filename, 'r'))
        #printpreview = wx.PrintPreview(printer, printer)
        #self.sizer.Add(printpreview, (0, 3), (1, 1), wx.ALL, border=5)
        
    
    
    def chooseAction(self, event):
        choice = self.radio1.GetSelection()
        if choice == 0:
            self.Bind(wx.EVT_BUTTON, self.runAuto, self.butt4)
            self.setStatusMessage('Auto Settings')

    
    def setStatusMessage(self, msg):
        self.statusbarText = wx.StaticText(self.statusbar, wx.ID_ANY, msg)
        self.statusbarText.SetForegroundColour(wx.BLACK)
        self.statusbar.AddWidget(self.statusbarText, pos = 0)
    
    
    def setRedStatusMessage(self, msg):
        self.statusbarText = wx.StaticText(self.statusbar, wx.ID_ANY, msg)
        self.statusbarText.SetForegroundColour(wx.RED)
        self.statusbar.AddWidget(self.statusbarText, pos = 0)
    
    
    def chooseSourceDir(self, event):
        dlg = wx.DirDialog(self, "Choose the source directory:")
        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()
            os.chdir(path)
            self.text1.SetValue(path)
        dlg.Destroy()

    
    def chooseTargetDir(self, event):
        dlg = wx.DirDialog(self, "Choose the target directory:")
        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()          
            self.text2.SetValue(path)
        dlg.Destroy()
        
    def refreshSourcePathLength(self, event):
        path = self.text1.GetValue()
        
        dimensions = self.text1.Size
        maxlength = dimensions[0] / self.avwidth
        curlength = len(path)
        
        
        paths = shortpath.shortpath(path)

        if curlength > maxlength:
            if path == paths[-1]:
                path = paths[-1]
            else:
                while curlength > maxlength:
                    path = paths[self.cuts]
                    curlength = len(path)
                    self.cuts += 1
        
        #else:
            #try:
                #self.cuts -= 1
                #print self.cuts
                #path = paths[self.cuts]
                #curlength = len(path)
            #except curlength > maxlength:
                #pass
                
        self.text1.SetValue(path)
        event.Skip()

    
    def runAuto(self, event):
        sourcepath = self.text1.GetValue()
        targetpath = self.text2.GetValue()
        if sourcepath == targetpath:
            self.setRedStatusMessage('Source and Target cant be the same!')  
        elif os.listdir(targetpath) != []:
            dlg = wx.MessageDialog(self, "Target folder isnt empty\nYou really want to continue?", 
                                   "Warning", 
                                   wx.YES_NO | wx.ICON_QUESTION | wx.NO_DEFAULT)
            if dlg.ShowModal() == 5104:
                dlg.Destroy()
            else:
                dlg.Destroy()
                AR.AutoRename(sourcepath, targetpath, 'txt')
                self.setStatusMessage('Finished!')
        else:
            AR.AutoRename(sourcepath, targetpath)
            self.setStatusMessage('Finished!')


    def runCustom(self, event):
        print 'Custom Settings'

    
    def onQuit(self, event=None):
        self.Close()




class Printer(wx.Printout):
    def __init__(self, frame, text = "", name = ""):
        "Prepares the Printing object.  Note: change current_y for 1, 1.5, 2 spacing for lines."
        wx.Printout.__init__(self)
        self.printer_config = wx.PrintData()
        self.printer_config.SetPaperId(wx.PAPER_LETTER)
        self.printer_config.SetOrientation(wx.LANDSCAPE)
        self.frame = frame
        self.doc_text = text
        self.doc_name = name
        self.current_y = 15  #y should be either (15, 22, 30)
        if self.current_y == 15:
            self.num_lines_per_page = 50
        elif self.current_y == 22:
            self.num_lines_per_page = 35
        else:
            self.num_lines_per_page = 25


    def Print(self, text, doc_name):
        "Prints the given text.  Currently doc_name logic doesn't exist.  E.g. might be useful for a footer.."
        self.doc_text = text
        self.doc_name = doc_name
        pdd = wx.PrintDialogData()
        pdd.SetPrintData(self.printer_config)
        printer = wxPrinter(pdd)
        if not printer.Print(self.frame,self):
            wx.MessageBox("Unable to print the document.")
        else:
            self.printer_config = printer.GetPrintDialogData().GetPrintData()

    def PreviewText(self, text, doc_name):
        "This function displays the preview window for the text with the given header."
        #try:
        self.doc_name = doc_name
        self.doc_text = text

        #Destructor fix by Peter Milliken -- with change to Printer.__init__()
        print1 = Printer(self.frame, text = self.doc_text, name = self.doc_name)
        print2 = Printer(self.frame, text = self.doc_text, name = self.doc_name)
        preview = wx.PrintPreview(print1, print2, self.printer_config)

        if not preview.Ok():
            wx.MessageBox("Unable to display preview of document.")
            return

        preview_window = wx.PreviewFrame(preview, self.frame, \
                                        "Print Preview - %s" % doc_name)
        preview_window.Initialize()
        preview_window.SetPosition(self.frame.GetPosition())
        preview_window.SetSize(self.frame.GetSize())
        preview_window.MakeModal(True)
        preview_window.Show(True)
        #except:
        #    wx.MessageBox(GetErrorText())

    def PageSetup(self):
        "This function handles displaying the Page Setup window and retrieving the user selected options."
        config_dialog = wx.PageSetupDialog(self.frame)   #replaces PrintDialog
        config_dialog.GetPageSetupData()
        print self.printer_config        
        config_dialog.ShowModal()
        self.printer_config = config_dialog.GetPageSetupData()
        print self.printer_config
        config_dialog.Destroy()

    def OnBeginDocument(self,start,end):
        "Do any end of document logic here."
        wx.Printout.OnBeginDocument(self,start,end)

    def OnEndDocument(self):
        "Do any end of document logic here."
        wx.Printout.OnEndDocument(self)

    def OnBeginPrinting(self):
        "Do printing initialization logic here."
        wx.Printout.OnBeginPrinting(self)

    def OnEndPrinting(self):
        "Do any post printing logic here."
        wx.Printout.OnEndPrinting(self)

    def OnPreparePrinting(self):
        "Do any logic to prepare for printing here."
        wx.Printout.OnPreparePrinting(self)

    def HasPage(self, page_num):
        "This function is called to determine if the specified page exists."
        return len(self.GetPageText(page_num)) > 0

    def GetPageInfo(self):
        """
        This returns the page information: what is the page range available, and what is the selected page range.
        Currently the selected page range is always the available page range.  This logic should be changed if you need
        greater flexibility.
        """

        minPage = 1
        maxPage = int(len(self.doc_text.split('\n'))/self.num_lines_per_page)
        fromPage, toPage = minPage, maxPage
        return (minPage,maxPage,fromPage,toPage)

    def OnPrintPage(self, page_num):
        "This function / event is executed for each page that needs to be printed."
        dc = self.GetDC()
        x,y = 25, self.current_y
        if not self.IsPreview():
            y *=4
        line_count = 1
        for line in self.GetPageText(page_num):
            dc.DrawText(line, x, y*line_count)
            line_count += 1

        return True

    def GetPageText(self, page_num):
        "This function returns the text to be displayed for the given page number."
        lines = self.doc_text.split('\n')
        lines_for_page = lines[(page_num -1)*self.num_lines_per_page: page_num*(self.num_lines_per_page-1)]
        return lines_for_page 



if __name__ == '__main__':
    app = wx.App()
    frame = MainFrame(None, title='AutoRename', size=(480, 600))
    frame.Show()
    app.MainLoop()
